// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.WindowsMobile.Status;
using svs.Mobile.BeyondMedia.FeedCore;
using svs.Mobile.BeyondMedia.Properties;
using svs.Mobile.BeyondMedia.UiCore;
using svs.Mobile.BeyondMedia.UiCore.GDI;
using svs.Mobile.BeyondScheduler.Core.Objects;
using svs.Mobile.BeyondScheduler.Core.Objects.Operations;

namespace svs.Mobile.BeyondMedia.Objects
{
	public class Helpers
	{
		#region Delegates

		public delegate void ActiveViewChangedEvent(object sender, ViewNames i_view);

		public delegate void FeedChangedEvent(Feed aTrack);

		public delegate void FeedSelectedEvent(Feed aFeed, FeedViewType i_view);

		public delegate void CategorySelectedEvent(FeedCategory aCategory);

		public delegate void NavigationEvent(object sender, NavigationDirection i_direction);

		public delegate void TrackSelectedEvent(Track aTrack);

		public delegate void TrackStateChangedEvent(object sender, Track i_track);


		public enum MediaEventInfo
		{
			MediaEnded,
			StreamPositionChanged,
			PlayError,
			Playing,
			Paused,
			Stopped
		}

		public delegate void TrackPlayStateChagedEvent(Track track, MediaEventInfo info);

		#endregion

		#region Public Methods

		public static ScheduledTask FirstScheduledUpdateTask
		{
			get
			{
				return ScheduledUpdateTasks[0];
			}
		}

		public static TaskRepository.ScheduledTaskList ScheduledUpdateTasks
		{
			get
			{
				var tasks = TaskRepository.GetTasksByOperationType(typeof(OperationStartBeyondPodUpdate));

				if (tasks.Count == 0)
				{
					var evt =
						new Event(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 6, 0, 0), 1,
						          new TimeSpan(1, 0, 0, 0));
					var op = new OperationStartBeyondPodUpdate
					         	{
					         		BeyondPodPath = Assembly.GetExecutingAssembly().GetName().CodeBase,
					         		CategoryToUpdate = CategoryManager.AllFeeds.Value
					         	};

					var task = new ScheduledTask(evt,op) { Active = false, MinBatteryLevelRequired = BatteryLevel.Low};

					TaskRepository.RegisterTask(task);
				}

				//Re-get and return
				return TaskRepository.GetTasksByOperationType(typeof(OperationStartBeyondPodUpdate));
			}
		}

		public static FeedCategory GetScheduledUpdateCategoryForTaskNumber(int taskNumber)
		{
			var task = TaskRepository.GetTaskById(TaskRepository.GetTaskIDFromNumber(taskNumber)) ??
			                     FirstScheduledUpdateTask;

			var category = ((OperationStartBeyondPodUpdate) task.Operation).CategoryToUpdate;
			return category == string.Empty ? CategoryManager.AllFeeds : CategoryManager.GetCategoryByValue(category);
		}

		public static void Beep()
		{
			MessageBeep(32);
		}

		public static void BeepAsterisk()
		{
			MessageBeep(0x00000040);
		}

		public static char GetAlternativeKey(char keyChar)
		{
			switch (keyChar)
			{
				case '1':
					return 'w';

				case '2':
					return 'e';

				case '3':
					return 'r';

				case '4':
					return 's';

				case '5':
					return 'd';

				case '6':
					return 'f';

				case '7':
					return 'x';

				case '8':
					return 'c';

				case '9':
					return 'v';

				default:
					return ' ';
			}
		}

		public static void DoPostInstalProcessing()
		{
			if(string.Compare(Configuration.ApplicationInstallPath,Configuration.FallBackInstallPath) == 0)
			{
				MessageBox.Show("Unable to determine the default BeyondPod Install Location!\nSoft reset of the device may fix this problem!","Fatal Error!",MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
				return;
			}

			string copy = Path.Combine(Configuration.ApplicationInstallPath, "TrackState.xml.copy");
			string org = copy.Replace(".xml.copy", ".xml");

			if (File.Exists((org)) && File.Exists(copy))
				File.Delete(copy);
			else if (File.Exists(copy) && !File.Exists(org))
				File.Move(copy, org);

			//In case the htm extension is not mapped correctly, we will stitch the default document extension
			//to bphtm, and adds the registry handlers to handle it.
			if (!Configuration.IsUsingAlternateDocumentFileExtension && !Configuration.IsHtmExtensionMappedCorrectly)
				Configuration.SwitchToAlternativeDocumentExtension();
		}


		public static int SystemScrollbarWidth
		{
			get
			{
				return GetSystemMetrics(2); //SM_CXVSCROLL
			}
		}


		[DllImport("coredll.dll")]
		public static extern int GetSystemMetrics(int index);


		[DllImport("coredll.dll")]
		public static extern int GetAsyncKeyState(int vkey);

		public static Color ChangeColorIntensity(Color color1, double d)
		{
			return
				Color.FromArgb(ChangeValueIntensity(color1.R, d), ChangeValueIntensity(color1.G, d),
				               ChangeValueIntensity(color1.B, d));
		}

		public static void NotifyOutOfMemory(Exception ex)
		{
			if (ex != null)
				CoreHelper.WriteLogEntry("!!! OUT OF MEMORY EXCEPTION !!!\n" + ex.StackTrace + "\n\n");

			MessageBoxEx.Show("There is not enough program memory to run BeyondPod. Please close some of the running applications!","Insufficient Memory!",
			                MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
		}

		public static void EnableFormCutCopyPaste(Form form)
		{
			if (PlatformDetection.IsSmartphone())
				return;

			Win32.SHInitExtraControls();

			IntPtr hWnd = Win32.CreateWindowEx(0, Win32.WC_SIPPREF, "", Win32.WS.CHILD,
					 0, 0, 0, 0, form.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
		}

		public static Control GetFocusedControl(Control parent)
		{
			if (parent.Focused)
				return parent;

			foreach (Control ctrl in parent.Controls)
			{
				var temp = GetFocusedControl(ctrl);

				if (temp != null)
					return temp;
			}
			return null;
		}

		public static void EnsureSIPDoesNotOverlapActiveControl(Form form, int visibleHeight)
		{
			Control c = GetFocusedControl(form);

			if (c == null)
				return;

			var overlap = c.Bottom + (c.Parent == form? 0 : c.Parent.Location.Y) - visibleHeight;

			if (overlap > 0)
				form.AutoScrollPosition = new Point(form.AutoScrollPosition.X, (form.AutoScrollPosition.Y * -1) + overlap);
		}

		#endregion

		#region Private methods

		[DllImport("Coredll.dll")]
		private static extern void MessageBeep(int Flags);

		private static int ChangeValueIntensity(int val, double d)
		{
			double nr = val;
			nr *= d;
			if (nr > 255)
				nr = 255;

			return (int) nr;
		}

		#endregion

		#region Global Enums

		#region MoveDirection enum

		public enum MoveDirection
		{
			Forward,
			Back
		}

		#endregion

		#region NavHintArrows enum

		public enum NavHintArrows
		{
			Left,
			Right,
			Both
		}

		#endregion

		#region NavigationDirection enum

		public enum NavigationDirection
		{
			Forward,
			Back,
			Up,
			Down
		}

		#endregion

		#region PlayerSkinOrientation enum

		public enum PlayerSkinOrientation
		{
			Portrait,
			Landscape,
			Unknown
		}

		#endregion

		#region RadioMode enum

		public enum RadioMode
		{
			Off,
			On,
			Discoverable,
		}

		#endregion

		#region ViewNames enum

		public enum ViewNames
		{
			Categories = 0,
			Feeds = 1,
			Tracks = 2,
			Player = 3,
			FeedContent = 4,
			WebBrowser = 5,
		}

		#endregion

		#endregion
	}
}